package com.deer.wms.ware.task.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.deer.wms.base.system.model.BillOutBO;
import com.deer.wms.base.system.model.BillOutDetailBO;
import com.deer.wms.base.system.model.Item.ItemInfo;
import com.deer.wms.base.system.service.ItemInfoService;
import com.deer.wms.inventory.model.Inventory.Inventory;
import com.deer.wms.inventory.service.InventoryService;
import com.deer.wms.project.root.service.SuperServiceImpl;
import com.deer.wms.project.root.util.DateUtils;
import com.deer.wms.project.root.util.HttpClient;
import com.deer.wms.system.manage.model.customer.Customer;
import com.deer.wms.ware.task.dao.SoDetailMapper;
import com.deer.wms.ware.task.model.Return.SoLogItemDto;
import com.deer.wms.ware.task.model.SO.*;
import com.deer.wms.ware.task.model.SO.vo.PickTaskVo;
import com.deer.wms.ware.task.model.SO.vo.SoDetailVo;
import com.deer.wms.ware.task.model.SO.vo.SoMasterVo;
import com.deer.wms.ware.task.model.pickTask.PickTask;
import com.deer.wms.ware.task.service.PickTaskService;
import com.deer.wms.ware.task.service.SoDetailService;
import com.deer.wms.ware.task.service.SoMasterService;
import com.mchange.v2.lang.ObjectUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by guo on 2020/02/02.
 */
@Service
@Transactional
public class SoDetailServiceImpl extends SuperServiceImpl<SoDetailMapper, SoDetail> implements SoDetailService {

    @Autowired
    private SoDetailMapper soDetailMapper;
    @Autowired
    private SoMasterService soMasterService;
    @Autowired
    private PickTaskService pickTaskService;
    @Autowired
    private InventoryService inventoryService;
    @Autowired
    private SoMasterServiceImpl soMasterServiceImpl;
    @Autowired
    private ItemInfoService itemInfoService;

    @Override
    public List<SoDetailDto> findList(SoDetailCriteria criteria) {
        return soDetailMapper.findList(criteria);
    }

    @Override
    public List<SoDetailDto> findBaoKuanByItemCode(String itemCode, Integer wareId, Integer orgId) {
        return soDetailMapper.findBaoKuanByItemCode(itemCode, wareId, orgId);
    }

    @Override
    public List<SoDetail> findByBillNo(String billNo) {
        SoDetailVo soDetailVo = new SoDetailVo();

        return soDetailMapper.findByBillNo(billNo);
    }

    @Override
    public List<SoDetailDto> findUndistributedSoDetail(Integer soType) {
        return soDetailMapper.findUndistributedSoDetail(soType);
    }

    @Override
    public List<SoDetail> findByMasterId(Integer soId) {
        return soDetailMapper.findByMasterId(soId);
    }

    @Override
    public List<SoDayList> findDayList(SoDetailCriteria criteria) {
        return soDetailMapper.findDayList(criteria);
    }

    @Override
    public List<SoLogItemDto> findLogItemsByBillNos(List<String> billNos) {
        return soDetailMapper.findLogItemsByBillNos(billNos);
    }

    @Override
    public List<SoDetailDto> findDetailsByWaveId(Integer wareId, Integer waveId) {
        return soDetailMapper.findDetailsByWaveId(wareId, waveId);
    }

    /**
     * 查询借料项 全部项
     *
     * @param billNo
     * @return
     */
    @Override
    public SoDetailVo findAll(String billNo) {
        SoDetailVo soDetailVo = new SoDetailVo();
        List<SoDetail> soDetailList = list(new QueryWrapper<SoDetail>().eq("bill_no", billNo));


        if (ObjectUtil.isNotEmpty(soDetailList)) {
            Set<String> itemCode = soDetailList.stream().map(SoDetail::getItemCode).collect(Collectors.toSet()); //获取所有itemCode
            List<Inventory> inventoryList = inventoryService.list(new QueryWrapper<Inventory>().in("item_code", itemCode));
            for (SoDetail soDetail : soDetailList) {
                // //货主id 88货主Id默认为 -1 自有, code SYS_MINE
                soDetail.setMarginQty(this.putNumber(inventoryList, soDetail.getItemCode(), -1));
            }
            soDetailVo.setAll(soDetailList); // 全部项
            soDetailVo.setLend(this.lendDetail(soDetailList));//借料项
        }
        return soDetailVo;
    }


    /**
     *
     * @param inventoryList 库存余量表
      * @param itemCode  物料编码
     * @return
     */
    public Double putNumber(List<Inventory> inventoryList, String itemCode,Integer  organizationId) {
        //入库数量-分配数量 -冻结数量   //货主id 88货主Id默认为 -1 自有, code SYS_MINE
        return inventoryList.stream().filter(item -> item.getItemCode().equals(itemCode) && item.getOrganizationId() == organizationId).mapToDouble(item ->
                item.getQuantity() - item.getAllotQuantity() - item.getFreezeQuantity()
        ).sum();

    }
    /**
     * 查询可借料项,全部项
     *
     * @param billNo
     * @param itemCode
     * @return
     */
    @Override
    public  List<BillOutDetailBO> beBeing(String billNo, String itemCode) {
        List<BillOutDetailBO> aLl = this.getALl();
        List<BillOutDetailBO> newBillOutDetailBO = aLl.stream().filter(item -> !item.getBillNo().equals(billNo) && item.getItemNumber().equals(itemCode)).collect(Collectors.toList());
        return newBillOutDetailBO;



    }

    //获取供料项
    public List<SoDetail> lendDetail(List<SoDetail> list) {
        return list.stream().filter(item -> item.getOrderQuantity() > item.getMarginQty()).collect(Collectors.toList());
    }


    //右边借料项


    //右边全部项


    public List<BillOutDetailBO>  getALl() {
        List<BillOutDetailBO> soDetailList = new ArrayList<>();
        try {
            String token = soMasterService.requestToken();
            if (token != null) {

                Map<String, String> map1 = new HashMap<>();

                map1.put("dateFrom", new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
                map1.put("dateFrom", "2022-05-15");
                //调用erp接口获取数据
                CloseableHttpClient client = HttpClients.createDefault();
                URIBuilder uriBuilder = new URIBuilder("https://syecrg.sieyuan.com:44398/api/Epichust/GetAllIMOutSourceBills");
                HttpPost post = new HttpPost(uriBuilder.build());
                StringEntity myEntity = new StringEntity(JSON.toJSONString(map1), "UTF-8");// 构造请求数据
                post.setHeader("Content-Type", "application/json");
                post.addHeader("Authorization", "Bearer " + token);
                post.setEntity(myEntity);// 设置请求体
                String responseContent = null; // 响应内容

                CloseableHttpResponse response = null;
                try {
                    response = client.execute(post);
                    HttpEntity entity = response.getEntity();
                    if (response.getStatusLine().getStatusCode() == 200) {
                        String content = EntityUtils.toString(entity, "UTF-8");
                        //订单数量
                        List<BillOutBO> po = (List<BillOutBO>) JSON
                                .parseArray(content, BillOutBO.class);
                        //获取所有详情信息
                        List<BillOutDetailBO> billOutDetailBOS = new ArrayList<>();
                        po.stream().map(item -> {
                            item.setDetails(soMasterServiceImpl.insertBillNo(item));
                            billOutDetailBOS.addAll(item.getDetails());
                            return item;
                        }).collect(Collectors.toList());
                        //单号去重

                        Set <String> oldBillNos = po.stream().map(BillOutBO::getBillNo).collect(Collectors.toSet());
                        if (ObjectUtil.isEmpty(oldBillNos)) {
                            return null;
                        }

                        Set<String> itemNumbers = billOutDetailBOS.stream().map(BillOutDetailBO::getItemNumber).collect(Collectors.toSet());
                        //获取所有物料
                        List<ItemInfo> itemInfoList = itemInfoService.list(new QueryWrapper<ItemInfo>().in("item_code", itemNumbers));
                        //新增详情

                        for (BillOutDetailBO billOutDetailBO : billOutDetailBOS) {
                            ItemInfo itemInfo = itemInfoList.stream().filter(item -> item.getItemCode().equals(billOutDetailBO.getItemNumber())).collect(Collectors.toList()).get(0);
                            if( itemInfo.getPickTacticCode() != "标准件" && itemInfo.getPickTacticCode() != "标准件-MRP物料" && itemInfo.getPickTacticCode() != "辅料-MRP物料" && itemInfo.getPickTacticCode() != "辅料"){
                                soDetailList.add(billOutDetailBO);
                            }

                        }



                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    try {
                        if (response != null)
                            response.close();

                    } catch (IOException e) {
                        e.printStackTrace();
                    } finally {
                        try {
                            if (client != null)
                                client.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();

        }
        return soDetailList;
    }

}
